﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using System.Xml.Linq;
using com.IronOne.BoardPACWinAppBO.Auth;
using com.IronOne.BoardPACWinAppBO.General;
using com.IronOne.BoardPACWinAppBO.Paper;
using com.IronOne.BoardPACWinAppBO.Settings;
using com.IronOne.BoardPACWinAppBO.Sync;
using com.IronOne.BoardPACWinAppUtil.Enums;
using com.IronOne.BoardPACWinAppUtil.Util;

namespace com.IronOne.BoardPACWinAppService.Xml
{
    internal class XmlToModelMapper
    {
        public static UserModel LogOnModelMapper(string xmlResult)
        {
            //TODO: incomplete model mapping, more data coming on XML, write all to database 
            try
            {
                var userModel = new UserModel();

                var xDocument = XDocument.Parse(xmlResult.Trim());
                var xData = xDocument.Element("Data");

                userModel.UserName = xData.Element("UserName").Value;
                userModel.UserId = Convert.ToInt32(xData.Element("UserID").Value);
                userModel.UserFullName = xData.Element("UserFullName").Value;
                userModel.IPadDisplayName = xData.Element("IPadDisplayName").Value;
                Global.IPadDisplayName = userModel.IPadDisplayName;
                userModel.DeviceRegistered = xData.Element("DeviceRegistered").Value;
                userModel.ResetPassword = Convert.ToBoolean(xData.Element("ResetPassword").Value);
                userModel.InitialLogin = Convert.ToBoolean(xData.Element("InitialLogin").Value);
                userModel.PasswordExpired = Convert.ToBoolean(xData.Element("PasswordExpired").Value);
                userModel.PasswordExpiredMessage = xData.Element("PasswordExpiredMessage").Value;
                userModel.PasswordPolicyText = xData.Element("PasswordPolicyText").Value;
                userModel.IsDisclaimerNoticeViewed = Convert.ToBoolean(xData.Element("IsDisclaimerNoticeViewed").Value);

                return userModel;
            }
            catch (Exception)
            {
                throw;
            }
        }

        internal static AppSettingModel AppSettingModelMapper(AppSettingModel asModel, ResponseDataModel rdm)
        {
            try
            {
                var xml = rdm.Data.ToString();
                var asm = asModel;

                var xDocument = XDocument.Parse(xml.Trim());
                var xResponse = xDocument.Element("Data");

                //Get these values from Sync 2
                //asm.AppOfflineUsageCheck = Convert.ToInt32(xResponse.Element("AppOfflineUsageCheck").Value.Trim());
                //asm.EnforceOnlineLoginDuration = Convert.ToInt32(xResponse.Element("EnforceOnlineLoginDuration").Value.Trim());
                //asm.OfflineConsecutiveLimit = Convert.ToInt32(xResponse.Element("OfflineConsecutiveLimit").Value.Trim());
                //asm.MaxOfflineLoginInterval = Convert.ToInt32(xResponse.Element("MaxOfflineLoginInterval").Value.Trim());

                if (asm.SyncFrequencySelected.Key.Equals("-1")) //Server decides
                {
                    var sfVal = xResponse.Element("SyncFrequence").Value.Trim();
                        //Value comes in seconds; Default val 60
                    asm.SyncFrequencyServerDecides = Convert.ToInt32(sfVal);
                }

                asm.CurrentWebVersion = rdm.WebAppVersion;

                //Output: 1 & 0.  1 means display on ui
                var ssInfo = Convert.ToInt32(xResponse.Element("ShowSupportInfo").Value.Trim());
                if (ssInfo != 1) return asm;

                asm.ShowSupportInfo = true;

                var support = xResponse.Element("Support");

                asm.SupportInfoName = support.Element("SupportName").Value.Trim();
                asm.SupportInfoEmails = support.Element("Emails").Element("Email").Value.Trim().Split(',');

                asm.SupportInfoPhones = support.Element("Phones").Element("phone").Value.Trim().Split(',');

                asm.DownloadUrl = xResponse.Element("DownloadUrl").Value.Trim();
                asm.ServerMessage = xResponse.Element("SrverMessage").Value.Trim();
                asm.ServerCommands = xResponse.Element("ServerCommands").Element("command").Value.Trim();
                return asm;
            }
            catch (Exception)
            {
                throw;
            }
        }

        internal static string GetDeviceAuthorizeStatus(string xmlData)
        {
            try
            {
                var xDocument = XDocument.Parse(xmlData.Trim());
                return xDocument.Element("Data").Element("DeviceStatus").Value.Trim();
            }
            catch (Exception)
            {
                throw;
            }
        }

        internal static DownloadDataModel SyncDownloadDataModelMapper(string data)
        {
            try
            {
                #region Tables

                const string pattern = "=\\s*''\\s*,";
                const string replacement = "=NULL,";
                var rgx = new Regex(pattern);
                data = rgx.Replace(data, replacement);

                var ddm = new DownloadDataModel();
                var xDocument = XDocument.Parse(data.Trim());
                var xData = xDocument.Element("Data");

                var queriesList = new List<List<string>>();
                List<string> queries = null;

                var xTables = xData.Elements("Tables");
                foreach (var xSql in xTables.Select(tbl => tbl.Elements("SQL")))
                {
                    queries = xSql.Select(qry => qry.Value.Trim()).ToList();
                    queriesList.Add(queries);
                }
                ddm.QueryData = queriesList;

                #endregion

                #region Gallery

                var xGallery = xData.Elements("Gallery");

                var gall = xGallery.FirstOrDefault();
                if ((gall == null) || (!gall.HasElements)) return ddm;

                var xImageSet = xData.Elements("Gallery").Elements("ImageSet");

                ddm.ImgType = xImageSet.Attributes("ImageType").FirstOrDefault().Value;
                queries.Add(xImageSet.Attributes("SQL").FirstOrDefault().Value);

                var xImage = xData.Elements("Gallery").Elements("ImageSet").Elements("Image");
                var imgList = xImage.ToDictionary(img => img.Attributes("Id").FirstOrDefault().Value, img => img.Value);
                ddm.ImageData = imgList;

                #endregion

                return ddm;
            }
            catch (Exception)
            {
                throw;
            }
        }

        internal static List<PastPaperModel> PastPapersModelMapper(string data)
        {
            var ppdModel = new List<PastPaperModel>();

            try
            {
                var xDocument = XDocument.Parse(data.Trim());
                var xResponse = xDocument.Element("Data");

                var paperNodesList = xResponse.Elements("Paper");
                const string path = "ms-appx:///Assets/Images/AgendaPage/";
                foreach (var pprElement in paperNodesList)
                {
                    var ppm = new PastPaperModel
                    {
                        DocName = pprElement.Element("DocName").Value,
                        PaperRefNo = (String.IsNullOrWhiteSpace(pprElement.Element("RefNo").Value))
                            ? " Not available"
                            : " " + pprElement.Element("RefNo").Value,
                        PaperId = Convert.ToInt32(pprElement.Element("DocID").Value),
                        PaperStatus = Convert.ToInt32(pprElement.Element("PaperStatus").Value)
                    };

                    var enumDisplayStatus = (PaperStatusCust) ppm.PaperStatus;
                    //var stringValue = enumDisplayStatus.ToString();

                    ppm.PaperStatusValue = enumDisplayStatus.ToString();

                    ppm.DocCreatedDateTime = Utility.GetDate(pprElement.Element("CreatedDate").Value);
                    ppm.MeetingSubCategory = pprElement.Element("MeetingName").Value;
                    ppm.Description = pprElement.Element("Description").Value;

                    ppm.MeetingDate = Utility.GetDate(pprElement.Element("MeetingDate").Value);
                    if (ppm.MeetingDate != null)
                        ppm.MeetingDateDisplay = ((DateTime) (ppm.MeetingDate)).ToString(Global.DateFormat);

                    ppm.DocType = Convert.ToByte(pprElement.Element("DocType").Value);
                    switch (ppm.DocType)
                    {
                        case (byte) DocumentType.BoardPaper:
                            ppm.DocTypeIconPath = path + "Agenda_IconA.png";
                            break;
                        case (byte) DocumentType.InformationPaper:
                            ppm.DocTypeIconPath = path + "Agenda_IconI.png";
                            break;
                        case (byte) DocumentType.DiscussionItem:
                            ppm.DocTypeIconPath = path + "Agenda_IconD.png";
                            break;
                        case (byte) DocumentType.SupportDocument:
                            ppm.DocTypeIconPath = path + "Agenda_IconS.png";
                            break;
                        case (byte) DocumentType.DiscussionPaper:
                            ppm.DocTypeIconPath = path + "Agenda_IconD.png";
                            break;
                        case (byte) DocumentType.AudioVideo:
                            ppm.DocTypeIconPath = path + "Agenda_IconV.png";
                            break;
                    }
                    ppm.VersionId = Convert.ToInt32(pprElement.Element("VersionID").Value);
                    ppm.SeVersion = Convert.ToInt32(pprElement.Element("VersionInfo").Value);
                    ppm.MeetingId = Convert.ToInt32(pprElement.Element("MeetingID").Value);
                    ppm.MeetingStatusValue = pprElement.Element("MeetingStatus").Value;
                    ppm.FileExtension = pprElement.Element("DocExtension").Value;

                    ppdModel.Add(ppm);
                }
            }
            catch (Exception)
            {
                throw;
            }
            return ppdModel;
        }
    }
}